package cn.com.citydo.base.util;

import com.alibaba.fastjson.JSONObject;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;

public class ResponseUtil {

    public final static String CONTENT_TYPE_HTML = "text/html";
    public final static String CONTENT_TYPE_XML = "text/xml";
    public final static String CONTENT_TYPE_JSON = "application/json";
    public final static String CONTENT_TYPE_SCRIPT = "application/x-javascript";
    public final static String CONTENT_TYPE_FILE = "multipart/form-data";
    public final static String CONTENT_TYPE_PDF = "application/pdf";
    public final static String CHARACTER_ENCODING = "UTF-8";
    public final static String CHARSET = ";charset=" + CHARACTER_ENCODING;

    private ResponseUtil() {
    }

    public static HttpServletResponse getResponse() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
    }

    public static HttpServletResponse sendRedirect(String url) {
        HttpServletResponse response = getResponse();
        try {
            response.sendRedirect(url);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }

    public static HttpServletResponse setContentType(HttpServletResponse response, String contentType) {
        if (response == null) {
            response = getResponse();
        }
        response.setContentType(contentType);
        return response;
    }

    public static HttpServletResponse setContentType(String contentType) {
        return setContentType(null, contentType);
    }

    public static HttpServletResponse setContentTypeAndCharset(HttpServletResponse response, String contentType, String charset) {
        return setContentType(response, contentType + CHARSET + charset);
    }

    public static HttpServletResponse setContentTypeAndCharset(String contentType, String charset) {
        return setContentType(null, contentType + CHARSET + charset);
    }

    public static HttpServletResponse setContentTypeDefaultCharset(String contentType) {
        HttpServletResponse response = setContentType(null, contentType + CHARSET);
        response.setCharacterEncoding(CHARACTER_ENCODING);
        return response;
    }

    public static HttpServletResponse write(String text) {
        return write(null, text);
    }

    public static HttpServletResponse write(HttpServletResponse response, String text) {
        if (response == null) {
            response = getResponse();
        }
        if (text == null) {
            text = "";
        }
        try (PrintWriter writer = response.getWriter()) {
            writer.write(text);
        } catch (IOException e) {
        }
        return response;
    }

    public static HttpServletResponse writeHtml(String text) {
        return write(setContentTypeDefaultCharset(ResponseUtil.CONTENT_TYPE_HTML), text);
    }

    public static HttpServletResponse writeXml(String text) {
        return write(setContentTypeDefaultCharset(ResponseUtil.CONTENT_TYPE_XML), text);
    }

    public static HttpServletResponse writeJson(String text) {
        return write(setContentTypeDefaultCharset(ResponseUtil.CONTENT_TYPE_JSON), text);
    }

    public static HttpServletResponse writeJson(JSONObject json) {
        return write(setContentTypeDefaultCharset(ResponseUtil.CONTENT_TYPE_JSON), JSONUtil.toJSONObjectStr(json));
    }

    public static HttpServletResponse writeScript(String text) {
        return write(setContentTypeDefaultCharset(ResponseUtil.CONTENT_TYPE_SCRIPT), text);
    }

    public static HttpServletResponse writeFile(HttpServletResponse response, File file, String fileName) {
        if (response == null) {
            response = ResponseUtil.setContentTypeDefaultCharset(CONTENT_TYPE_FILE);
        }
        try {
            response.setHeader("Content-Disposition", "attachment;fileName=" + new String(fileName.getBytes(CHARACTER_ENCODING), "iso-8859-1"));
            writeToResponse(file, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

    public static HttpServletResponse writePDFFile(HttpServletResponse response, File file, String fileName) {
        if (response == null) {
            response = ResponseUtil.setContentTypeDefaultCharset(CONTENT_TYPE_PDF);
        }
        try {
            response.setHeader("Content-Disposition", "inline;fileName=" + new String(fileName.getBytes(CHARACTER_ENCODING), "iso-8859-1"));
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Headers", "accept,content-type");
            response.setHeader("Access-Control-Allow-Methods", "OPTIONS,GET,POST,DELETE,PUT");
            writeToResponse(file, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

    public static HttpServletResponse redirect2Url(String url) {
        HttpServletResponse response = getResponse();
        response.setStatus(301);
        response.setHeader("Location", url);
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Cache-Control", "no-store");
        response.setDateHeader("Expires", 0);
        return response;
    }

    public static HttpServletResponse writeJpg(BufferedImage image) {
        return writeImage(image, "image/jpeg");
    }

    public static HttpServletResponse writeImage(BufferedImage image, String contentType) {
        HttpServletResponse response = ResponseUtil.getResponse();
        response.setContentType(contentType);
        try (OutputStream out = response.getOutputStream()) {
            String formatName = null;
            if (contentType.contains("image/")) {
                formatName = contentType.substring(6);
            } else if (contentType.contains("application/x-")) {
                formatName = contentType.substring(14);
            }
            ImageIO.write(image, formatName, out);
        } catch (NullPointerException ne) {
            //访问图片中途中断连接报空指针异常没法控制 增加catch
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

    public static String writeImage(File image) {
        return writeImage(image, getImageContentType(image), null);
    }

    public static String writeImage(File image, HttpServletResponse response) {
        return writeImage(image, getImageContentType(image), response);
    }

    public static String writeImage(File image, String contentType, HttpServletResponse response) {
        if (response == null) {
            response = ResponseUtil.getResponse();
        }
        response.setContentType(contentType);
        response.setHeader("Cache-Control", "max-age=2628000");
        response.setDateHeader("Expires", System.currentTimeMillis() + 2628000000L);
        writeToResponse(image, response);
        return null;
    }

    private static String getImageContentType(File file) {
        String filename = file.getName().toLowerCase();
        if (filename.endsWith("jpg") || filename.endsWith("jpeg")) {
            return "image/jpeg";
        }
        if (filename.endsWith("gif")) {
            return "image/gif";
        }
        if (filename.endsWith("png")) {
            return "image/png";
        }
        if (filename.endsWith("bmp")) {
            return "application/x-bmp";
        }
        return "";
    }

    private static void writeToResponse(File file, HttpServletResponse response) {
        try {
            try (InputStream in = new FileInputStream(file)) {
                try (OutputStream os = response.getOutputStream()) {
                    byte[] b = new byte[1024];
                    int length;
                    while ((length = in.read(b)) > 0) {
                        os.write(b, 0, length);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
